﻿using System.Threading.Tasks;
using System.Web.Mvc;
using SDCloudSolution.SDCloud.Web.Infrastructure;
using SDCloudSolution.SDCloud.Web.Infrastructure.Interfaces;
using SDCloudSolution.SDCloud.Web.Models;

namespace SDCloudSolution.SDCloud.Web.Controllers
{
    [RoutePrefix("modelruns")]
    [Authorize]
    public partial class ModelRunsController : Controller
    {
        private readonly IModelRunViewModelProvider _modelRunViewModelProvider;
        private readonly IModelResultViewModelProvider _modelResultViewModelProvider;
        private readonly IModelStatisticsViewModelProvider _modelStatisticsViewModelProvider;
        private readonly ICultureInfoProvider _cultureInfoProvider;
        private readonly ModelResultsCsvConverter _resultsCsvConverter;

        public ModelRunsController(
            IModelRunViewModelProvider modelRunViewModelProvider, 
            IModelResultViewModelProvider modelResultViewModelProvider,
            IModelStatisticsViewModelProvider modelStatisticsViewModelProvider,
            ICultureInfoProvider cultureInfoProvider,
            ModelResultsCsvConverter resultsCsvConverter
        )
        {
            _modelRunViewModelProvider = modelRunViewModelProvider;
            _modelResultViewModelProvider = modelResultViewModelProvider;
            _modelStatisticsViewModelProvider = modelStatisticsViewModelProvider;
            _cultureInfoProvider = cultureInfoProvider;
            _resultsCsvConverter = resultsCsvConverter;
        }

        [Route("list")]
        [HttpGet]
        public virtual async Task<ActionResult> List(PagingModel paging = null)
        {
            paging = PagingModel.Default;

            var model = await _modelRunViewModelProvider.GetListAsync(paging);

            return View(model);
        }

        [Route("list/{modelId}")]
        [HttpGet]
        public virtual async Task<ActionResult> ListForModel(int modelId, PagingModel paging = null)
        {
            paging = PagingModel.Default;

            var model = await _modelRunViewModelProvider.GetListFromModelAsync(modelId, paging);

            return View(model);
        }

        [Route("{modelRunId}")]
        [HttpGet]
        public virtual async Task<ActionResult> View(int modelRunId)
        {
            var model = await _modelRunViewModelProvider.GetModelRunViewModelAsync(modelRunId);

            return View(model);
        }

        [Route("create")]
        [HttpGet]
        public virtual ActionResult CreatePage(int modelId)
        {
            return null;
        }

        [Route("create")]
        [HttpPost]
        public virtual ActionResult Create()
        {
            return null;
        }

        [Route("{modelId}/quick-start")]
        [HttpPost]
        public virtual async Task<ActionResult> QuickStart(int modelId)
        {
            await _modelRunViewModelProvider.QuickStartForModelAsync(modelId);

            return RedirectToAction(MVC.Models.View(modelId));
        }

        [Route("{modelRunId}/cancel")]
        [HttpPost]
        public virtual async Task<ActionResult> Cancel(int modelRunId)
        {
            await _modelRunViewModelProvider.CancelModelRunAsync(modelRunId);

            return RedirectToAction(MVC.ModelRuns.View(modelRunId));
        }

        [Route("{modelRunId}/delete")]
        [HttpPost]
        public virtual ActionResult Delete(int modelRunId)
        {
            return null;
        }

        [Route("{modelRunId}/download/json")]
        [HttpGet]
        public virtual async Task<ActionResult> DownloadAsJson(int modelRunId)
        {
            var data = await _modelResultViewModelProvider.GetModelResultDataAsync(modelRunId);

            Response.AddHeader("Content-Disposition", $"attachment;filename=model-results-{modelRunId}.json");
            return Json(data, JsonRequestBehavior.AllowGet);
        }

        [Route("{modelRunId}/download/csv")]
        [HttpGet]
        public virtual async Task<ActionResult> DownloadAsCsv(int modelRunId)
        {
            var data = await _modelResultViewModelProvider.GetModelResultDataAsync(modelRunId);

            var cultureInfo = _cultureInfoProvider.RetriveCultureInfoFromRequest(Request);
            var resultsStream = await _resultsCsvConverter.ConvertToContentAsync(data, cultureInfo);

            Response.AddHeader("Content-Disposition", $"attachment;filename=model-results-{modelRunId}.csv");
            return new FileStreamResult(resultsStream, "text/csv");
        }

        [ChildActionOnly]
        public virtual async Task<ActionResult> ActiveModelRunsWidget()
        {
            var model = await _modelRunViewModelProvider.GetActiveListAsync(new PagingModel
            {
                PageIndex = 0,
                PageSize = 5
            });

            return PartialView(MVC.ModelRuns.Views._WidgetList, model);
        }

        [ChildActionOnly]
        public virtual async Task<ActionResult> ModelRunStatisticsWidget()
        {
            var model = await _modelStatisticsViewModelProvider.GetModelStatisticsForUserAsync();

            return PartialView(MVC.ModelRuns.Views._WidgetStatistics, model);
        }
    }
}